/*******************************************************************************
 * Witz - Winboard Chess Engine                                                *
 * MOVEORDERING.C                                                              *
 *                                                                             *
 * Contain's move-ordering code not related to hash tables                     *
 *                                                                             *
 * Please refer to the licence notice in MAIN.C                                *
 *                                                                             *
 * Copywright (C) 2006 Pradu Kannan                                            *
 * http://witz.sf.net/                                                         *
 ******************************************************************************/

#include "build.h"
#include "defs.h"
#include "protos.h"
#include "data.h"

int hh[64][64]; //history heustric table
move killers[MAX_PLY]; //killer moves

/*resetHH()
 *resets the history heustric
 */
void resetHH()
{
	char i,j;
	for(i=0;i<64;i++)
		for(j=0;j<64;j++)
			hh[i][j]=-KILLERVAL;
}

/*resetKillers()
 *resets the killer heustric
 */
void resetKillers()
{
	int i;
	for(i=0;i<MAX_PLY;i++)
		killers[i]=NULLMOVE;
}

/*updateHH()
 *update's the history heustric (incremented by d^2)
 *
 *@param m - the move to be used to update the hh
 *@param d - the depth left
 */
void updateHH(move m, const short d)
{
	if(hh[extractFrom(m)][extractTo(m)]<KILLERVAL) //don't allow values above KillerVAL
		hh[extractFrom(m)][extractTo(m)]+=d<0?0:d*d;
}

/*updateHH()
 *update's the killer heustric
 *
 *@param m - the move to be used to update the killers
 *@param d - the depth from root
 */
void updateKiller(move m, const short dfr)
{
	if(dfr<MAX_PLY)
		killers[dfr]=m;
}

/*findHH()
 *find's the HH value for the move
 *
 *@param m - the move to be scored
 *
 *@returns - the hh value of the move
 */
int findHH(move m)
{
	return hh[extractFrom(m)][extractTo(m)];
}

/*sort()
 *sorts a move list (bubble sort)
 *
 *@param list - the move list
 */
void sort(moveList* list)
{
	short i, j;
	smove temp;

	for (i = (list->moveCount - 1); i >= 0; i--)
		for (j = 1; j <= i; j++)
			if (list->moves[j-1].score < list->moves[j].score)
			{
				temp = list->moves[j-1];
				list->moves[j-1] = list->moves[j];
				list->moves[j] = temp;
			}
}

/*scoreMove()
 *does the scoring of a move
 *Ordered by
 *1) Hashed move from the transposition tables
 *2) "good" capture moves sorted by SEE
 *3) killer moves (newly added - not yet implemented)
 *4) history moves
 *5) statically pre-sorted remaining moves
 *6) bad capture moves sorted by SEE
 *
 *@param pos - the board position
 *@param move - the move to be scored
 *
 *@returns the score for the position
 */
int scoreMove(const board* pos, move m)
{
	int score=SEE(pos,m);
	if(score>0)
		return score+SEEVAL+pieceSquare[pos->side][extractPiece(m)][extractTo(m)]-pieceSquare[pos->side][extractPiece(m)][extractFrom(m)];
	else if(score<0)
		return score-SEEVAL+pieceSquare[pos->side][extractPiece(m)][extractTo(m)]-pieceSquare[pos->side][extractPiece(m)][extractFrom(m)];
	score=findHH(m)+pieceSquare[pos->side][extractPiece(m)][extractTo(m)]-pieceSquare[pos->side][extractPiece(m)][extractFrom(m)];
	if(extractCapture(m))
		score+=ORDERING_CAPTURE_BONUS;
	return score;
	//the hashed move is done in the search
}
